package 极客时间.concurrence.并发编程实战篇.手写一把lock;

import java.util.Iterator;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.LockSupport;

/**
 * @Author idea
 * @Date created in 10:04 下午 2020/7/22
 */
public abstract class BacAQS {

    /**
     * 占有资源的独有者
     */
    volatile AtomicReference<Thread> owner = new AtomicReference<>();

    /**
     * 等待锁资源的线程
     */
    volatile LinkedBlockingQueue<Thread> awaiter = new LinkedBlockingQueue<>();

    public boolean tryAcquire() { // 交给使用者去实现。 模板方法设计模式
        //不支持的操作异常
        throw new UnsupportedOperationException();
    }

    public boolean tryRelease() {
        throw new UnsupportedOperationException();
    }

    /**
     * 尝试加锁 lock
     */
    public void acquire() {
        //获取锁失败的尝试失败
        while (!this.tryAcquire()) {
            awaiter.add(Thread.currentThread());
            LockSupport.park();
            awaiter.remove(Thread.currentThread());
        }
    }

    /**
     * 释放锁 unlock
     */
    public void release() {
        if (tryRelease()) {
            Iterator<Thread> iterator = awaiter.iterator();
            while (iterator.hasNext()) {
                Thread next = iterator.next();
                if (null != next) {
                    LockSupport.unpark(next);
                }
            }
        }
    }
}
